package com.partvoyage.server.service.geoname;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import org.geonames.Address;
import org.geonames.WebService;
import org.geonames.WikipediaArticle;

import com.partvoyage.server.service.geoname.exception.GeonameServiceException;
import com.partvoyage.server.utils.Configuration;
import com.partvoyage.shared.GeonameWikiPediaBean;

/**
 * voir : http://www.geonames.org/source-code/javadoc/
 * http://www.geonames.org/source-code/
 * http://www.geonames.org/export/ws-overview.html
 * http://www.geonames.org/export/wikipedia-webservice.html
 * 
 * Sinon pour aller plus loin: Wrapper webservice:
 * http://svn.apache.org/repos/asf
 * /incubator/stanbol/trunk/enhancer/engines/geonames
 * /src/main/java/org/apache/stanbol
 * /enhancer/engines/geonames/impl/GeonamesAPIWrapper.java
 * 
 * @author ludovic
 * 
 */
public class GeonameWebService extends WebService {

	public final static String LANGUAGE = "en";
	public final static int RANK = 20;
	public final static int MAX_ELEMENTS_BEAN_IN_LIST = 20;
	public final static int RADIUS = 20;
	public final static int MAX_ROWS = 10;
	private static GeonameWebService INSTANCE;

	public static GeonameWebService getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new GeonameWebService();
		}
		return INSTANCE;
	}

	private GeonameWebService() {
		WebService.setUserName(Configuration.getGeonameUserName());
	}

	/**
	 * TODO
	 * 
	 * @param latitude
	 * @param longitude
	 * @param radius
	 *            : in km
	 * @return la liste des GeonameWikiPediaBean pour la latitude et longitude
	 *         (seul les MAX_ELEMENTS_BEAN_IN_LIST seront retournés, ils feront
	 *         partis des meilleurs RANK) suivantes
	 * @throws GeonameServiceException
	 */
	@SuppressWarnings("unchecked")
	public List<GeonameWikiPediaBean> getGeonameWikiPediaBean(Double latitude,
			Double longitude) throws GeonameServiceException {
		List<GeonameWikiPediaBean> list = new LinkedList<GeonameWikiPediaBean>();
		List<WikipediaArticle> listWiki = null;
		try {
			listWiki = WebService.findNearbyWikipedia(latitude, longitude,
					RADIUS, LANGUAGE, 100);
		} catch (Exception e) {
			throw new GeonameServiceException(e);
		}
		Collections.sort(listWiki, WikipediaArticle.RANK_ORDER);
		int compt = 0;
		for (WikipediaArticle wikipediaArticle : listWiki) {
			if (compt++ >= MAX_ELEMENTS_BEAN_IN_LIST) {
				break;
			}
			GeonameWikiPediaBean geonameWikiPediaBean = new GeonameWikiPediaBean();
			geonameWikiPediaBean.setWikipediaUrl(wikipediaArticle
					.getWikipediaUrl());
			geonameWikiPediaBean.setLatitude(wikipediaArticle.getLatitude());
			geonameWikiPediaBean.setLongitude(wikipediaArticle.getLongitude());
			geonameWikiPediaBean.setThumbnailImg(wikipediaArticle
					.getThumbnailImg());
			list.add(geonameWikiPediaBean);

		}

		return list;
	}

	/**
	 * 
	 * @param latitude
	 * @param longitude
	 * @return the name of place according to the latitude and longitude
	 * @throws GeonameServiceException
	 */
	public String getPlaceName(Double latitude, Double longitude)
			throws GeonameServiceException {
		Address adresse = null;
		try {
			adresse = WebService.findNearestAddress(37.451, -122.18);
			
		} catch (IOException e) {
			throw new GeonameServiceException(e);
		} catch (Exception e) {
			throw new GeonameServiceException(e);
		}
		if (adresse == null) {
			return null;
		}
		System.out.println("adresse récupérée du webservice " + adresse);
		return adresse.getPlaceName();
	}

}
